/*
This file is part of MMM.

MMM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

MMM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with MMM.  If not, see <http://www.gnu.org/licenses/>.
*
* @package    MMM
* @author     Nikolaus Vahrenkamp
* @copyright  2013 High Performance Humanoid Technologies (H2T), Karlsruhe, Germany
*
*/

#ifndef _MMM_ModelProcessorFactory_h_
#define _MMM_ModelProcessorFactory_h_

#include "../MMMCore.h"
#include "../AbstractFactoryMethod.h"
#include "../MMMImportExport.h"
#include "ModelProcessor.h"
#include <boost/shared_ptr.hpp>
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <string>
#include "../RapidXML/rapidxml.hpp"

namespace MMM
{

/*!
	This Factory is used to make custom ModelProcessors accessible by the MMM framework.
	An exemplary implementation may look like this
	
	\code
	class MMM_IMPORT_EXPORT MyCustomModelProcessorFactory  : public ModelProcessorFactory
	{
	public:
	EIGEN_MAKE_ALIGNED_OPERATOR_NEW

		MyCustomModelProcessorFactory() 
		{
			// some init code
		}
		virtual ~MyCustomModelProcessorFactory()
		{
			// some exit code
		}

		ModelProcessorPtr createModelProcessor()
		{
			ModelProcessorPtr processor(new MyCustomModelProcessor());
			return processor;
		}

		static std::string getName() {return "MyCustomModelProcessorFactory"};
		static boost::shared_ptr<ModelProcessorFactory> createInstance(void*)
		{
			boost::shared_ptr<ModelProcessorFactory> processorFactory(new MyCustomModelProcessorFactory());
			return processorFactory;
		}
	private:
		static SubClassRegistry registry;
		// be sure to initialize class in cpp file:
		// ConverterFactory::SubClassRegistry MyCustomModelProcessorFactory::registry(MyCustomModelProcessorFactory::getName(), &MyCustomModelProcessorFactory::createInstance);
	};
	//
	\endcode
*/
class MMM_IMPORT_EXPORT ModelProcessorFactory : public AbstractFactoryMethod<ModelProcessorFactory, void*>
{
public:

	ModelProcessorFactory() { ; }
	virtual ~ModelProcessorFactory() { ; }

	virtual ModelProcessorPtr createModelProcessor() = 0;

	/*!
	Convenient method to create a model processor via an XML config file.
	The XML tag '<ModelProcessorConfig type='FactoryName'>' is used to identitfy the factory, which is used to create a model processor.
	The model processor is intiialized with the passed config file.
	*/
	static ModelProcessorPtr fromConfigFile(const std::string &configFile);

	/*!
	Convenient method to create a model processor via an XML configiguration that is stored within a motion tag.
	The XML tag '<ModelProcessorConfig type='FactoryName'>' is used to identitfy the factory, which is used to create a model processor.
	The model processor is intiialized with the passed config file.
	@param motionFile The xml file.
	@param motionName The motions are scanned for the attribute name. If empty the first motion is used.
	*/
	static ModelProcessorPtr fromMotionFile(const std::string &motionFile, const std::string &motionName);

	static ModelProcessorPtr getModelProcessorFromNode(rapidxml::xml_node<>* node);

protected:
    static rapidxml::xml_node<>* getConfigNode(rapidxml::xml_node<>* node);
};

typedef boost::shared_ptr<ModelProcessorFactory> ModelProcessorFactoryPtr;


} // namespace MMM

#endif // _MMM_ModelProcessorFactory_h_
